package com.honey.solr;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.java.plugin.PluginLifecycleException;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.honey.configureation.ConfigurationPlugin;
import com.honey.configureation.holder.ConfigurationHolder;
import com.honey.configureation.holder.ProjectEnvironmentHolder;
import com.honey.configureation.xmlparser.ParseElement;
import com.honey.core.NullPlugin;
import com.honey.core.types.FullyQualifiedJavaType;
import com.honey.core.utils.ObjectFactory;
import com.honey.core.utils.StringUtility;
import com.honey.solr.analyzer.Analyzer;

public class SolrPlugin extends NullPlugin implements ConfigurationHolder {
	
	private String targetClassName="SolrDaoSupport";
	
	private String targetPackage="dao";
	
	private String targetEntityPackage="";
	
	private String targetEntitySuffix = "";
	
	private boolean targetEntityTrim = false;
	
	
	private int httpClientVersion= 3 ;
	
	private String queryForPage = null;
	
	private ProjectEnvironmentHolder projectEnvironmentHolder = null ;
	
	private String solrSchemaFile = null;
	
	private String uniqueKey = "id";
	
	private String schemaName = "FullTextSearch";
	
	private Analyzer analyzer= Analyzer.GENERAL;
	
	private List<SchemaField> schemaFields = new ArrayList<SchemaField>();

	private boolean targetEntitySerializable;

	private boolean targetEntityToString;

	private boolean targetEntityFinalMethod;

	private boolean targetEntitySetterReturnThis;

	private String targetModelPackage;

	private String targetModelClassSuffix="";

	private String targetModelFieldEnumSuffix;

	private String solrSpringContextFile = null;
	
	private boolean supporHighlight = true;
	private Map<String, String> solrServers= new HashMap<String, String>();
	
	@Override
	public void parserElement(Element element, Properties properties) {
		//
		Element ele = ParseElement.getElementsByTagName(element, "javaSolrDaoSupportGenerator");
		
		String tmp = ParseElement.getConfiguration(ele, "targetClassName", properties);
		if(tmp != null){
			targetClassName = tmp;
		}
		
		tmp = ParseElement.getConfiguration(ele, "targetPackage", properties);
		if(tmp != null)targetPackage = tmp;
		
		tmp = ParseElement.getConfiguration(ele, "queryForPage", properties);
		if(tmp != null)queryForPage = tmp;
		
		tmp = ParseElement.getConfiguration(ele, "apacheHttpClientVersion", properties);
		if(tmp != null){
			try {
				httpClientVersion = Integer.parseInt(tmp);
			} catch (NumberFormatException e) {
			}
		}
		//
		ele = ParseElement.getElementsByTagName(element, "javaSolrSpringContext");
		if(ele != null){
			solrSpringContextFile = ParseElement.getConfiguration(ele, "solrSpringContextFile", properties);
			tmp = ParseElement.getConfiguration(ele, "supporHighlight", properties);
			supporHighlight = StringUtility.isTrue(tmp);
			
			NodeList nl = ele.getElementsByTagName("solrServer");
			int length = nl.getLength() ;
			if( length > 1){
				for( int i =0;i < length; i++  ){
					Element ns =(Element)nl.item(i);
					String name = ParseElement.getConfiguration(ns, "name", properties);
					String url = ParseElement.getConfiguration(ns, "url", properties);
					if( name == null ){
						name ="solrServer" + i;
					}
					if( url == null ){
						url ="http://127.0.0.1:8080/solr/";
					}
					solrServers.put(name, url);
				}
			}else if(length == 1){
				Element ns =(Element)nl.item(0);
				String url = ParseElement.getConfiguration(ns, "url", properties);
				if( url == null ){
					url ="http://127.0.0.1:8080/solr/";
				}
				
				solrServers.put(SolrConstant.SOLR_SERVER_FIELD_NAME, url);
			}
		}
		
		//
		ele = ParseElement.getElementsByTagName(element, "javaEntityGenerator");
		tmp = ParseElement.getConfiguration(ele, "targetPackage", properties);
		if(tmp != null)targetEntityPackage = tmp;
		
		tmp = ParseElement.getConfiguration(ele, "classSuffix", properties);
		if(tmp != null)targetEntitySuffix = tmp;
		
		tmp = ParseElement.getConfiguration(ele, "trimStrings", properties);
		if(StringUtility.isTrue(tmp))targetEntityTrim  = true;
		
		tmp = ParseElement.getConfiguration(ele, "serializable", properties);
		if(StringUtility.isTrue(tmp))targetEntitySerializable  = true ;
		
		tmp = ParseElement.getConfiguration(ele, "overrideToString", properties);
		if(StringUtility.isTrue(tmp))targetEntityToString  = true ;
		
		tmp = ParseElement.getConfiguration(ele, "finalMethod", properties);
		if(StringUtility.isTrue(tmp))targetEntityFinalMethod  = true ;
		
		tmp = ParseElement.getConfiguration(ele, "setterReturnThis", properties);
		if(StringUtility.isTrue(tmp))targetEntitySetterReturnThis  = true ;
		//
		ele = ParseElement.getElementsByTagName(element, "schema");
		tmp = ParseElement.getConfiguration(ele, "analyzer", properties);
		if(tmp != null){
			if("ik".equalsIgnoreCase(tmp) || "ikanalyzer".equalsIgnoreCase(tmp)|| "ik-analyzer".equalsIgnoreCase(tmp)){
				analyzer = Analyzer.IKAnalyzer;
			}else if("mmseg4j".equalsIgnoreCase(tmp) || "mmseg".equalsIgnoreCase(tmp)){
				analyzer =  Analyzer.MMSEG4J;
			}
			;
		}
		tmp = ParseElement.getConfiguration(ele, "schemaFile", properties);
		if(tmp != null)solrSchemaFile = tmp;
		
		tmp = ParseElement.getConfiguration(ele, "uniqueKey", properties);
		if(tmp != null)uniqueKey = tmp;
		
		tmp = ParseElement.getConfiguration(ele, "name", properties);
		if(tmp != null)schemaName = tmp;
		
		Element fields = ParseElement.getElementsByTagName(ele, "fields");
		if( fields!= null ){
			NodeList nodeList = fields.getElementsByTagName("field");
			if(nodeList != null){
				for(int i=0,size= nodeList.getLength();i<size;i++ ){
					Properties p = ParseElement.parseAttributes((Element)nodeList.item(i), properties);
					SchemaField schemaField = new SchemaField();
					Object value = p.remove("name");
					if( value != null ){
						String s = value.toString();
						if( s.length() >0 ){
							schemaField.setName(s);
							schemaField.setUniqueKey(uniqueKey.equals( s ));
						}else{
							continue;
						}
					}else{
						continue;
					}
					
					value = p.remove("comment");
					if(value != null ){
						schemaField.setComment(value.toString());
					}
					
					value = p.remove("indexed");
					if(value != null ){
						schemaField.setIndexed(StringUtility.isTrue( value.toString() ));
					}
					value = p.remove("stored");
					if(value != null ){
						schemaField.setStored(StringUtility.isTrue( value.toString() ));
					}
					value = p.remove("required");
					if(value != null ){
						schemaField.setRequired(StringUtility.isTrue( value.toString() ));
					}
					
					value = p.remove("type");
					if(value != null ){
						schemaField.setType(new SolrFullyQualifiedJavaType( analyzer != Analyzer.GENERAL, value.toString()) );
					}else{
						schemaField.setType(new SolrFullyQualifiedJavaType( analyzer != Analyzer.GENERAL,"String") );
					}
					schemaField.setProperties(p);
					schemaFields.add(schemaField);
				}
				
				//
				ele = ParseElement.getElementsByTagName(element, "javaModelGenerator");
				tmp = ParseElement.getConfiguration(ele, "targetPackage", properties);
				if(tmp != null)targetModelPackage = tmp;
				
				tmp = ParseElement.getConfiguration(ele, "classSuffix", properties);
				if(tmp != null)targetModelClassSuffix = tmp;
				
				tmp = ParseElement.getConfiguration(ele, "tableFieldEnumSuffix", properties);
				if(tmp != null)targetModelFieldEnumSuffix = tmp;
				
				
			}
		}
	}

	public ProjectEnvironmentHolder getProjectEnvironmentHolder(){
		if( projectEnvironmentHolder == null ){
			try {
				projectEnvironmentHolder=
					((ConfigurationPlugin)ObjectFactory.getRequestPlugin(this, "honey.configuration.plugin")
							).getContextInstant().getProjectEnvironmentHolder();
			} catch (PluginLifecycleException e) {
				e.printStackTrace();
			}
		}
		return projectEnvironmentHolder;
	}
	@Override
	public String toXmlElement() {
		return null;
	}

	@Override
	public void validate() {
		
	}

	public String getTargetClassName() {
		return targetClassName;
	}

	public String getTargetPackage() {
		return targetPackage;
	}

	public int getHttpClientVersion() {
		return httpClientVersion;
	}

	/**
	 * @return the queryForPage
	 */
	public final String getQueryForPage() {
		return queryForPage;
	}

	/**
	 * @return the solrSchemaFile
	 */
	public final String getSolrSchemaFile() {
		return solrSchemaFile;
	}

	public String getUniqueKey() {
		return uniqueKey;
	}

	public void setUniqueKey(String uniqueKey) {
		this.uniqueKey = uniqueKey;
	}

	public Analyzer getAnalyzer() {
		return analyzer;
	}

	public List<SchemaField> getSchemaFields() {
		return schemaFields;
	}
	
	public String getSchemaName() {
		return schemaName;
	}

	public String getTargetEntityPackage() {
		return targetEntityPackage;
	}

	/**
	 * @return the targetEntitySuffix
	 */
	public final String getTargetEntitySuffix() {
		return targetEntitySuffix;
	}

	/**
	 * @return the targetEntityTrim
	 */
	public final boolean isTargetEntityTrim() {
		return targetEntityTrim;
	}

	/**
	 * @return the targetEntitySerializable
	 */
	public final boolean isTargetEntitySerializable() {
		return targetEntitySerializable;
	}

	/**
	 * @return the targetEntityToString
	 */
	public final boolean isTargetEntityToString() {
		return targetEntityToString;
	}

	/**
	 * @return the targetEntityFinalMethod
	 */
	public final boolean isTargetEntityFinalMethod() {
		return targetEntityFinalMethod;
	}

	/**
	 * @return the targetEntitySetterReturnThis
	 */
	public final boolean isTargetEntitySetterReturnThis() {
		return targetEntitySetterReturnThis;
	}

	/**
	 * @return the targetModelPackage
	 */
	public final String getTargetModelPackage() {
		return targetModelPackage;
	}

	/**
	 * @return the targetModelClassSuffix
	 */
	public final String getTargetModelClassSuffix() {
		return targetModelClassSuffix;
	}

	/**
	 * @return the targetModelFieldEnumSuffix
	 */
	public final String getTargetModelFieldEnumSuffix() {
		return targetModelFieldEnumSuffix;
	}
	
	public Map<String, String> getSolrServers() {
		return solrServers;
	}

	public String getSolrSpringContextFile() {
		return solrSpringContextFile;
	}

	public boolean isSupporHighlight() {
		return supporHighlight;
	}
	
	
}
